home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Grab Bag
/
Shareware Grab Bag.iso
/
090
/
pctj8403.arc
/
EX4PRIM.ASM
< prev
next >
Wrap
Assembly Source File
|
1984-01-30
|
17KB
|
464 lines
; ROUTINES FOR CHAPTER 4 - GRAPHICS - ELEMENTARY FUNCTIONS
;
; For 320 x 200 color graphics mode
;
;**********************************************************
datas segment public
;
public x0,y0,x1,y1,x2,y2
public color
;
; public parameters
x0 dw ?
y0 dw ?
x1 dw ?
y1 dw ?
x2 dw ?
y2 dw ?
color dw ?
;
; tables of color masks for filling boxes
cbytes db 000h, 055h, 0AAh, 0FFh
;
xtable dw 0FFC0h, 0FFF0h, 0FFFCh, 0FFFFh
dw 03FC0h, 03FF0h, 03FFCh, 03FFFh
dw 00FC0h, 00FF0h, 00FFCh, 00FFFh
dw 003C0h, 003F0h, 003FCh, 003FFh
;
; table of color masks for plotting points
ctable dw 0003Fh,0403Fh,0803Fh,0C03Fh
dw 000CFh,010CFh,020CFh,030CFh
dw 000F3h,004F3h,008F3h,00CF3h
dw 000FCh,001FCh,002FCh,003FCh
;
datas ends
;**********************************************************
video segment at 0B800h
video ends
;**********************************************************
ex4prim segment
;
public cls
public setpt,xorpt,locate
public setbox,xorbox
;
assume cs:ex4prim,ds:datas,es:video
;
;----------------------- routine begins -------------------------------+
; ROUTINE TO CLEAR THE GRAPHICS SCREEN
;
cls proc far;
push cx ; save registers
push ax
;
; set up the registers
mov cx,2000h ; word count of whole screen
mov ax,0 ; zero pattern for the screen
mov di,ax ; set starting address
cld ; go in forward direction
;
; clear the screen with a single string operation
rep stosw ; this clears the screen
;
pop ax ; restore registers
pop cx
ret
cls endp
;----------------------- routine ends --------------------------------+
;----------------------- routine begins -------------------------------+
; ROUTINE TO PLOT A POINT ON MEDIUM RES COLOR SCREEN
;
setpt proc far
;
push bx ; save registers
push si
push ax
;
; multiply y-coord by bytes per row and adjust for even/odd lines
mov ax,di ; get y-coord into low part
mov ah,al ; and into high part
and ax,01FEh ; mask off unwanted parts
sal ax,1 ; times 4
sal ax,1 ; times 8
sal ax,1 ; times 16
mov bx,ax ; goes into address
and bh,7 ; without adjustment
sal ax,1 ; times 32
sal ax,1 ; times 64
add bx,ax ; address gets y-coord times 80
;
; add x-coord to address
mov ax,si ; get x-coordinate
sar ax,1 ; divide
sar ax,1 ; by 4
add bx,ax ; here is the address
;
; compute the rotated mask and color
and si,3 ; just pixel position into the index
sal si,1 ; index times 2
sal si,1 ; index times 4
add si,dx ; 4*pixel position + color
sal si,1 ; 8*pixel position + 2*color
mov ax,ctable[si] ; look up rotated color and mask
;
; insert the color into the video byte
and al,es:[bx] ; get old byte & remove old pixel
or al,ah ; insert new color
mov es:[bx],al ; put the byte back
;
pop ax ; restore registers
pop si
pop bx
ret
;
setpt endp
;----------------------- routine ends --------------------------------+
;----------------------- routine begins ------------------------------+
; ROUTINE TO XOR A POINT ONTO MEDIUM RES COLOR SCREEN
;
xorpt proc far
;
push bx ; save registers
push si
push ax
;
; multiply y-coord by bytes per row and adjust for even/odd lines
mov ax,di ; get y-coord into low part
mov ah,al ; and into high part
and ax,01FEh ; mask off unwanted parts
sal ax,1 ; times 4
sal ax,1 ; times 8
sal ax,1 ; times 16
mov bx,ax ; goes into address
and bh,7 ; without adjustment
sal ax,1 ; times 32
sal ax,1 ; times 64
add bx,ax ; address gets y-coord times 80
;
; add x-coord to address
mov ax,si ; get x-coordinate
sar ax,1 ; divide
sar ax,1 ; by 4
add bx,ax ; here is the address
;
; compute the mask for color and use it
and si,3 ; just the bit count into the index
sal si,1 ; index times 2
sal si,1 ; index times 4
add si,dx ; 4*pixel position + color
sal si,1 ; 8*pixel position + 2*color
mov ax,ctable[si] ; look up the masks
xor es:[bx],ah ; xor the byte with the color
;
pop ax ; restore registers
pop si
pop bx
ret
;
xorpt endp
;----------------------- routine ends --------------------------------+
;----------------------- routine begins ------------------------------+
; ROUTINE TO RETURN COLOR OF A POINT ON MEDIUM RES COLOR SCREEN
;
locate proc far
;
push bx ; save registers
push cx
;
; multiply y-coord by bytes per row and adjust for even/odd lines
mov ax,di ; get y-coord into low part
mov ah,al ; and into high part
and ax,01FEh ; mask off unwanted parts
sal ax,1 ; times 4
sal ax,1 ; times 8
sal ax,1 ; times 16
mov bx,ax ; goes into address
and bh,7 ; without adjustment
sal ax,1 ; times 32
sal ax,1 ; times 64
add bx,ax ; address gets times 64 + times 16
;
; add x-coord to address
mov ax,si ; get x-coordinate
sar ax,1 ; divide
sar ax,1 ; by 4
add bx,ax ; here is the address
;
; compute the position of the pixel in the byte
mov cx,si ; use x-coordinate to determine count
and cx,3 ; just the bit count
inc cx ; plus one
sal cx,1 ; 2 bits per pixel
;
; get the byte and rotate into place
mov al,es:[bx] ; get old byte
rol al,cl ; rotate left this many times
and ax,3 ; just the pixel color
;
pop cx ; restore the registers
pop bx
ret
;
locate endp
;----------------------- routine ends --------------------------------+
;----------------------- routine begins ------------------------------+
; ROUTINE TO FILL A RECTANGULAR BOX
;
setbox proc far
;
push si ; save registers
push di
push dx
push bx
push cx
push ax
;
; determine byte position for start
;
; get y contribution
mov ax,y1 ; get starting y-coordinate
mov ah,al ; replicate for odd/even bank
and ax,1FEh ; just one bit gets moved
sal ax,1 ; times 4
sal ax,1 ; times 8
sal ax,1 ; times 16
mov di,ax ; address gets 16 times y-coordinate
and di,7FFh ; not the odd/even bit
sal ax,1 ; times 32
sal ax,1 ; times 64
add di,ax ; address gets 80 times y-coordinate
;
; add in x contribution
mov ax,x1 ; get x-coordinate
sar ax,1 ; divide
sar ax,1 ; by 4
add di,ax ; beginning offset
;
; count for outer loop
mov cx,y2 ; ending y-coordinate
sub cx,y1 ; minus starting y-coordinate
inc cx ; plus one
;
; count for inner loop
mov si,x2 ; ending x-coordinate
sar si,1 ; divide
sar si,1 ; by 4
mov ax,x1 ; starting x-coordinate
sar ax,1 ; divide
sar ax,1 ; by 4
sub si,ax ; take the difference
;
; get the color
mov bx,color ; get the color
and bx,3 ; just between 0 and 3
mov dl,cbytes[bx] ; look up color pattern
;
; determine mask for start and ending bytes
mov bx,x1 ; starting byte
and bx,3 ; just the pixel position
sal bx,1 ; times 2
sal bx,1 ; times 4
mov ax,x2 ; ending byte
and ax,3 ; just the pixel position
add bx,ax ; 4*starting+ending
sal bx,1 ; 8*starting+2*ending
mov bx,xtable[bx] ; look up the masks
;
; set up masked color bytes
mov dh,dl ; color for left bytes
mov ah,dl ; color for middle bytes
and dx,bx ; mask left and right color bytes
;
cld ; forward
;
sboxloop:
push cx ; save count of outer loop
push di ; save initial byte position
;
mov cx,si ; count for inner loop
;
; check for only one byte
mov al,bh ; get the mask
jcxz sboxloop2 ; if ending byte coincides
;
; color leftmost byte of the scan line
not al ; reverse the mask for clearing
and al,es:[di] ; get byte from memory and clear pixels
or al,dh ; put color in place
stosb ; put byte in place
;
; check for just two bytes
dec cx ; count the byte
jcxz sboxloop1 ; done?
;
; color middle bytes of the scan line
mov al,ah ; color for middle bytes
rep stosb ; put middle bytes in place
;
; handle rightmost byte of the scan line
;
; come here if two or more bytes
sboxloop1:
mov al,0FFh ; set full mask
;
; in any case come here to adjust the masks
sboxloop2:
and al,bl ; bring in right part of mask
and dl,al ; clear left part of color if needed
;
; color the byte
not al ; reverse the mask for clearing
and al,es:[di] ; get byte from memory and clear pixels
or al,dl ; put pixels in the byte
stosb ; put byte back into video RAM
;
; compute next scan line
pop di ; retore address of left side of box
test di,2000h ; odd or even line?
jz sboxloop3 ; skip if even
add di,80 ; add 80 bytes per line
sboxloop3:
xor di,2000h ; changes banks in any case
pop cx ; restore count for outer loop
loop sboxloop ; next scan line
;
pop ax ; restore registers
pop cx
pop bx
pop dx
pop di
pop si
ret
;
setbox endp
;----------------------- routine ends --------------------------------+
;----------------------- routine begins ------------------------------+
; ROUTINE TO XOR A RECTANGULAR BOX
;
xorbox proc far
;
push si ; save registers
push di
push dx
push bx
push cx
push ax
;
; determine byte position for start
;
; get y contribution
mov ax,y1 ; get starting y-coordinate
mov ah,al ; replicate for odd/even bank
and ax,1FEh ; just one bit gets moved
sal ax,1 ; times 4
sal ax,1 ; times 8
sal ax,1 ; times 16
mov di,ax ; address gets 16 times y-coordinate
and di,7FFh ; not the odd/even bit
sal ax,1 ; times 32
sal ax,1 ; times 64
add di,ax ; address gets 80 times y-coordinate
;
; add in x contribution
mov ax,x1 ; get x-coordinate
sar ax,1 ; divide
sar ax,1 ; by 4
add di,ax ; beginning offset
;
; count for outer loop
mov cx,y2 ; ending y-coordinate
sub cx,y1 ; minus starting y-coordinate
inc cx ; plus one
;
; count for inner loop
mov si,x2 ; ending x-coordinate
sar si,1 ; divide
sar si,1 ; by 4
mov ax,x1 ; starting x-coordinate
sar ax,1 ; divide
sar ax,1 ; by 4
sub si,ax ; take the difference
;
; get the color
mov bx,color ; get the color
and bx,3 ; just between 0 and 3
mov dl,cbytes[bx] ; look up color pattern
;
; determine mask for start and ending bytes
mov bx,x1 ; starting byte
and bx,3 ; just the pixel position
sal bx,1 ; times 2
sal bx,1 ; times 4
mov ax,x2 ; ending byte
and ax,3 ; just the pixel position
add bx,ax ; 4*starting+ending
sal bx,1 ; 8*starting+2*ending
mov bx,xtable[bx] ; look up the masks
;
; set up masked color bytes
mov dh,dl ; color for left bytes
mov ah,dl ; color for middle bytes
and dx,bx ; mask left and right color bytes
;
cld ; forward direction
;
xboxloop:
push cx ; save count for outer loop
push di ; save address of leftmost byte
;
mov cx,si ; count for inner loop
;
; check if only one byte in a scan line
mov al,bh ; get the mask
jcxz xboxloop3 ; ending byte coincides
;
; xor the leftmost byte
xor es:[di],dh ; xor color into memory
inc di ; next byte
dec cx ; count it
jcxz xboxloop2 ; done?
;
; xor the middle bytes
xboxloop1:
xor es:[di],ah ; xor color byte into memory
inc di ; next byte
loop xboxloop1 ; loop to get all the middle
;
; handle the rightmost byte
;
; come here if two or more bytes
xboxloop2:
mov al,0FFh ; set full mask
;
; in any case come here to adjust
xboxloop3:
and al,bl ; bring in right part
and dl,al ; mask the color if needed
;
; xor the rightmost byte
xor es:[di],dl ; xor byte into memory
inc di ; next byte
;
pop di ; restore the leftmost address
test di,2000h ; odd or even scan line?
jz xboxloop4 ; skip if even
add di,80 ; add 80 if odd
xboxloop4:
xor di,2000h ; switch banks in any case
pop cx ; restore count of outer loop
loop xboxloop ; loop for next scan line
;
pop ax ; restore registers
pop cx
pop bx
pop dx
pop di
pop si
ret
;
xorbox endp
;----------------------- routine ends --------------------------------+
ex4prim ends ; end of code segment
;
end